#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include "sfts_client_api.h"
#include "client.h"
#include "gui_bridge.h"

// 添加声明 - 会话状态检查函数
static int check_and_restore_session(void);

// 全局客户端会话
static client_session_t g_session;
static int g_is_initialized = 0;

// 保存最后一次成功登录的用户名和密码，用于自动重连
static char g_last_username[64] = {0};
static char g_last_password[64] = {0};
static char g_last_server_ip[64] = {0};
static int g_last_server_port = 0;

// 传输进度监控线程数据
typedef struct
{
    char filename[256];
    int is_running;
    pthread_t thread_id;
    int cancel_flag;
    pthread_mutex_t mutex;
} progress_monitor_t;

static progress_monitor_t g_progress_monitor = {0};

// 传输进度监控线程函数
static void *transfer_progress_thread(void *arg)
{
    progress_monitor_t *monitor = (progress_monitor_t *)arg;
    char filename[256];

    pthread_mutex_lock(&monitor->mutex);
    strncpy(filename, monitor->filename, sizeof(filename) - 1);
    filename[sizeof(filename) - 1] = '\0';
    pthread_mutex_unlock(&monitor->mutex);

    int last_percentage = -1; // 初始化为-1以确保第一次进度被上报
    int current_percentage = 0;
    int initial_update_sent = 0; // 确保至少发送一次0%进度

    while (1)
    {
        pthread_mutex_lock(&monitor->mutex);
        int should_cancel = monitor->cancel_flag;
        pthread_mutex_unlock(&monitor->mutex);

        if (should_cancel)
        {
            sfts_ui_on_transfer_complete(filename, 0, "传输已取消");
            break;
        }

        uint64_t transferred = 0, total = 0;
        int transfer_status = client_get_transfer_progress(&g_session, &transferred, &total);

        if (!initial_update_sent && total > 0)
        {
            sfts_ui_on_transfer_progress(filename, 0, "开始传输...");
            initial_update_sent = 1;
        }

        if (transfer_status == TRANSFER_STATE_ACTIVE || (transfer_status == TRANSFER_STATE_STARTING && total > 0))
        {
            if (total > 0)
            {
                current_percentage = (int)((transferred * 100) / total);
                if (current_percentage != last_percentage)
                {
                    last_percentage = current_percentage;
                    const char *status_msg = "传输中...";
                    if (current_percentage >= 100)
                        status_msg = "验证中..."; // 理论上在ACTIVE状态不会到100%
                    sfts_ui_on_transfer_progress(filename, current_percentage, status_msg);
                }
            }
        }
        else if (transfer_status == TRANSFER_STATE_COMPLETED)
        {
            sfts_ui_on_transfer_progress(filename, 100, "完成");
            sfts_ui_on_transfer_complete(filename, 1, "传输完成");
            break;
        }
        else if (transfer_status == TRANSFER_STATE_ERROR)
        {
            sfts_ui_on_transfer_complete(filename, 0, "传输出错");
            break;
        }
        else if (transfer_status == TRANSFER_STATE_CANCELLED)
        {
            sfts_ui_on_transfer_complete(filename, 0, "传输已取消");
            break;
        }
        else if (transfer_status == TRANSFER_STATE_NONE)
        {
            // 传输可能尚未开始或已被重置，如果不是由于取消，则可能是一个意外状态
            if (!should_cancel)
            { // 避免在取消后再次报告错误
                fprintf(stderr, "[ProgressThread] 传输状态为NONE，可能传输已结束或未正确开始\n");
                // 决定是否报告为错误，或只是安静退出
                // sfts_ui_on_transfer_complete(filename, 0, "传输状态未知");
            }
            break;
        }

        usleep(200000); // 每200毫秒更新一次
    }

    pthread_mutex_lock(&monitor->mutex);
    monitor->is_running = 0;
    pthread_mutex_unlock(&monitor->mutex);

    return NULL;
}

// 启动传输进度监控
static int start_progress_monitor(const char *filename)
{
    // 如果已有监控线程在运行，先停止它
    if (g_progress_monitor.is_running)
    {
        pthread_mutex_lock(&g_progress_monitor.mutex);
        g_progress_monitor.cancel_flag = 1;
        pthread_mutex_unlock(&g_progress_monitor.mutex);

        pthread_join(g_progress_monitor.thread_id, NULL);
    }

    // 初始化监控数据
    if (pthread_mutex_init(&g_progress_monitor.mutex, NULL) != 0)
    {
        fprintf(stderr, "Failed to initialize mutex\n");
        return -1;
    }

    pthread_mutex_lock(&g_progress_monitor.mutex);
    memset(g_progress_monitor.filename, 0, sizeof(g_progress_monitor.filename));
    strncpy(g_progress_monitor.filename, filename, sizeof(g_progress_monitor.filename) - 1);
    g_progress_monitor.cancel_flag = 0;
    g_progress_monitor.is_running = 1;
    pthread_mutex_unlock(&g_progress_monitor.mutex);

    // 创建监控线程
    if (pthread_create(&g_progress_monitor.thread_id, NULL, transfer_progress_thread, &g_progress_monitor) != 0)
    {
        fprintf(stderr, "Failed to create progress monitor thread\n");
        pthread_mutex_destroy(&g_progress_monitor.mutex);
        return -1;
    }

    return 0;
}

// 停止传输进度监控
static void stop_progress_monitor()
{
    if (g_progress_monitor.is_running)
    {
        pthread_mutex_lock(&g_progress_monitor.mutex);
        g_progress_monitor.cancel_flag = 1;
        pthread_mutex_unlock(&g_progress_monitor.mutex);

        pthread_join(g_progress_monitor.thread_id, NULL);
        pthread_mutex_destroy(&g_progress_monitor.mutex);
    }
}

// 实现会话状态检查函数
static int check_and_restore_session(void)
{
    // 如果客户端未初始化或者会话状态不是已认证，尝试恢复会话
    if (!g_is_initialized || g_session.state != SESSION_STATE_AUTHENTICATED)
    {
        // 记录当前状态
        int current_state = g_is_initialized ? g_session.state : -1;

        // 只在内部日志记录，不显示给用户
        fprintf(stderr, "[API] 检测到会话状态异常 (状态: %d)，尝试恢复连接...\n", current_state);

        // 如果有保存的登录信息，尝试重新登录
        if (g_last_username[0] != '\0' && g_last_password[0] != '\0' &&
            g_last_server_ip[0] != '\0' && g_last_server_port > 0)
        {

            // 如果有正在进行的传输，先停止它
            if (g_is_initialized && g_session.current_transfer.state == TRANSFER_STATE_ACTIVE)
            {
                stop_progress_monitor();
                // 不调用cancel，因为连接可能已经异常
            }

            // 如果已初始化，先断开连接
            if (g_is_initialized)
            {
                client_disconnect(&g_session);
                client_cleanup();
                g_is_initialized = 0;
            }

            // 重新初始化连接
            if (sfts_client_init_connection(g_last_server_ip, g_last_server_port) == 0)
            {
                // 重新登录
                fprintf(stderr, "[API] 尝试自动重新登录...\n");
                sfts_client_login(g_last_username, g_last_password);

                // 对用户只显示简洁的提示
                sfts_ui_on_log_message("正在恢复会话连接...", 0);

                return 1; // 表示尝试了恢复
            }
            else
            {
                sfts_ui_on_log_message("连接服务器失败，请重新登录", 1);
                return -1; // 恢复失败
            }
        }
        else
        {
            sfts_ui_on_log_message("会话已断开，请重新登录", 1);
            return -1; // 无法恢复
        }
    }

    return 0; // 会话状态正常
}

// 成功登录后的延迟处理
static void handle_delayed_login_success(const char *username)
{
    // 只是内部记录，不显示给用户
    fprintf(stderr, "[API] 用户 %s 登录成功，准备重置客户端状态...\n", username);

    // 如果有计划中的文件列表刷新请求，可以在这里执行
    // 先让客户端界面完全初始化，3秒后尝试主动刷新根目录
    usleep(3000000); // 3秒

    // 如果需要重新获取文件列表
    sfts_client_request_file_list(".");
}

// 初始化连接到服务器
int sfts_client_init_connection(const char *server_ip, int port)
{
    // 保存服务器信息，用于可能的自动重连
    strncpy(g_last_server_ip, server_ip, sizeof(g_last_server_ip) - 1);
    g_last_server_ip[sizeof(g_last_server_ip) - 1] = '\0';
    g_last_server_port = port;

    if (!g_is_initialized)
    {
        if (client_init() != 0)
        {
            fprintf(stderr, "Failed to initialize client\n");
            return -1;
        }

        if (client_session_init(&g_session) != 0)
        {
            fprintf(stderr, "Failed to initialize client session\n");
            return -1;
        }

        g_is_initialized = 1;
    }

    if (client_connect(&g_session, server_ip, port) != 0)
    {
        fprintf(stderr, "Failed to connect to server %s:%d\n", server_ip, port);
        return -1;
    }

    if (client_key_exchange(&g_session) != 0)
    {
        fprintf(stderr, "Failed to perform key exchange\n");
        return -1;
    }

    return 0;
}

// 用户登录
int sfts_client_login(const char *username, const char *password)
{
    if (!g_is_initialized || g_session.sock < 0 || g_session.state < SESSION_STATE_KEY_EXCHANGED)
    {
        fprintf(stderr, "Client not initialized or not connected\n");
        return -1;
    }

    // 保存登录信息，用于可能的自动重连
    strncpy(g_last_username, username, sizeof(g_last_username) - 1);
    strncpy(g_last_password, password, sizeof(g_last_password) - 1);
    g_last_username[sizeof(g_last_username) - 1] = '\0';
    g_last_password[sizeof(g_last_password) - 1] = '\0';

    int ret = client_authenticate(&g_session, username, password);
    if (ret == 0)
    {
        // 登录成功，通过GUI桥接通知UI
        sfts_ui_on_login_result(1, username);

        // 登录成功后，创建线程执行一些延迟处理
        pthread_t delayed_thread;
        char *username_copy = strdup(username);
        if (username_copy)
        {
            if (pthread_create(&delayed_thread, NULL,
                               (void *(*)(void *))handle_delayed_login_success,
                               (void *)username_copy) == 0)
            {
                pthread_detach(delayed_thread); // 分离线程，让它自行结束
            }
            else
            {
                free(username_copy); // 创建线程失败时释放内存
            }
        }
    }
    else
    {
        // 登录失败，通过GUI桥接通知UI
        sfts_ui_on_login_result(0, "用户名或密码错误");
    }

    return 0; // 返回0表示请求已处理，实际登录结果通过回调通知
}

// 用户注册
int sfts_client_register(const char *username, const char *password)
{
    if (!g_is_initialized || g_session.sock < 0 || g_session.state < SESSION_STATE_KEY_EXCHANGED)
    {
        fprintf(stderr, "Client not initialized or not connected\n");
        return -1;
    }

    int ret = client_register(&g_session, username, password);

    // 注册结果也可以通过GUI桥接回调通知UI
    if (ret == 0)
    {
        sfts_ui_on_registration_result(1, username);
    }
    else
    {
        sfts_ui_on_registration_result(0, "注册失败，用户可能已存在或服务器错误");
    }

    return ret;
}

// 请求文件列表
int sfts_client_request_file_list(const char *path)
{
    // 检查并尝试恢复会话状态
    int check_result = check_and_restore_session();
    if (check_result != 0)
    {
        // 会话状态异常，并且恢复尝试已启动或失败
        if (check_result > 0)
        {
            // 不再向UI发送错误，静默处理重连
            // 用户只会看到之前显示的"正在恢复会话连接..."
            sfts_ui_on_file_list_error(path, "正在恢复连接，请稍候");
        }
        else
        {
            // 连接已断开的情况
            sfts_ui_on_file_list_error(path, "连接已断开");
        }
        return -1;
    }

    if (!g_is_initialized || g_session.sock < 0 || g_session.state != SESSION_STATE_AUTHENTICATED)
    {
        fprintf(stderr, "[API] Client not authenticated for file list request\n");
        sfts_ui_on_file_list_error(path, "连接已断开");
        return -1;
    }

    void *raw_file_list = NULL;
    int file_count = 0;
    file_info_t *client_file_entries = NULL; // 使用 file_info_t 替代 file_entry_t

    fprintf(stderr, "[API] Requesting file list for path: %s\n", path);
    int ret = client_get_file_list(&g_session, path, &raw_file_list, &file_count);

    if (ret == 0)
    {
        fprintf(stderr, "[API] Successfully retrieved file list for path: %s, Count: %d\n", path, file_count);
        client_file_entries = (file_info_t *)raw_file_list; // 使用 file_info_t进行类型转换

        if (file_count > 0 && client_file_entries != NULL)
        {
            sfts_FileListItem_C *gui_items = (sfts_FileListItem_C *)malloc(file_count * sizeof(sfts_FileListItem_C));
            if (gui_items)
            {
                for (int i = 0; i < file_count; i++)
                {
                    // 名称转换
                    strncpy(gui_items[i].name, client_file_entries[i].filename, sizeof(gui_items[i].name) - 1);
                    gui_items[i].name[sizeof(gui_items[i].name) - 1] = '\0';

                    // 类型转换
                    strncpy(gui_items[i].type, client_file_entries[i].is_dir ? "directory" : "file", sizeof(gui_items[i].type) - 1);
                    gui_items[i].type[sizeof(gui_items[i].type) - 1] = '\0';

                    // 大小转换
                    gui_items[i].size = client_file_entries[i].size;

                    // 权限转换 (简化示例)
                    if (client_file_entries[i].is_dir)
                    {
                        snprintf(gui_items[i].permissions, sizeof(gui_items[i].permissions), "dr--"); // 目录通常可读
                    }
                    else
                    {
                        char p[4] = "---";
                        if (client_file_entries[i].has_read_permission)
                            p[0] = 'r';
                        if (client_file_entries[i].has_write_permission)
                            p[1] = 'w';
                        // 假设无执行权限显示
                        strncpy(gui_items[i].permissions, p, sizeof(gui_items[i].permissions) - 1);
                    }
                    gui_items[i].permissions[sizeof(gui_items[i].permissions) - 1] = '\0';

                    // 最后修改时间转换
                    time_t mod_time = (time_t)client_file_entries[i].modified_time;
                    struct tm *tm_info = localtime(&mod_time);
                    if (tm_info)
                    {
                        strftime(gui_items[i].lastModified, sizeof(gui_items[i].lastModified), "%Y-%m-%d %H:%M:%S", tm_info);
                    }
                    else
                    {
                        strncpy(gui_items[i].lastModified, "N/A", sizeof(gui_items[i].lastModified) - 1);
                        gui_items[i].lastModified[sizeof(gui_items[i].lastModified) - 1] = '\0';
                    }
                }
                sfts_ui_on_file_list_updated(gui_items, file_count);
                free(gui_items); // 释放转换后的列表
            }
            else
            {
                fprintf(stderr, "[API] Malloc failed for gui_items in sfts_client_request_file_list\n");
                sfts_ui_on_file_list_error(path, "客户端内存不足");
            }
        }
        else // file_count is 0 or client_file_entries is NULL (and ret == 0)
        {
            // 列表为空，也是成功状态，传递 NULL 和 0 给UI层
            sfts_ui_on_file_list_updated(NULL, 0);
        }

        if (raw_file_list) // 释放 client_get_file_list 分配的原始列表
        {
            free(raw_file_list);
        }
    }
    else
    {
        fprintf(stderr, "[API] Failed to retrieve file list for path: %s, Error code: %d\n", path, ret);
        sfts_ui_on_file_list_error(path, "无法获取文件列表");
    }

    return ret;
}

// 上传文件
int sfts_client_upload_file(const char *local_path, const char *remote_path)
{
    // 检查并尝试恢复会话状态
    int check_result = check_and_restore_session();
    if (check_result != 0)
    {
        // 会话状态异常，并且恢复尝试已启动或失败
        if (check_result > 0)
        {
            sfts_ui_on_log_message("正在恢复连接，请稍后再次尝试上传", 1);
        }
        else
        {
            sfts_ui_on_log_message("连接已断开，无法上传文件", 1);
        }
        return -1;
    }

    if (!g_is_initialized || g_session.sock < 0 || g_session.state != SESSION_STATE_AUTHENTICATED)
    {
        fprintf(stderr, "Client not authenticated\n");
        return -1;
    }

    sfts_ui_on_log_message("开始上传文件...", 0);

    // 开始文件传输
    int ret = client_upload_file(&g_session, local_path, remote_path);

    if (ret != 0)
    {
        sfts_ui_on_log_message("上传文件请求失败", 1);
        return ret;
    }

    // 提取文件名
    char basename[256];
    const char *last_slash = strrchr(local_path, '/');
    if (!last_slash)
    {
        last_slash = strrchr(local_path, '\\');
    }

    if (last_slash)
    {
        strncpy(basename, last_slash + 1, sizeof(basename) - 1);
        basename[sizeof(basename) - 1] = '\0';
    }
    else
    {
        strncpy(basename, local_path, sizeof(basename) - 1);
        basename[sizeof(basename) - 1] = '\0';
    }

    // 初始进度报告
    sfts_ui_on_transfer_progress(basename, 0, "上传初始化...");

    // 启动进度监控线程
    start_progress_monitor(basename);

    return 0;
}

// 下载文件
int sfts_client_download_file(const char *remote_path, const char *local_path)
{
    // 检查并尝试恢复会话状态
    int check_result = check_and_restore_session();
    if (check_result != 0)
    {
        // 会话状态异常，并且恢复尝试已启动或失败
        if (check_result > 0)
        {
            sfts_ui_on_log_message("正在恢复连接，请稍后再次尝试下载", 1);
        }
        else
        {
            sfts_ui_on_log_message("连接已断开，无法下载文件", 1);
        }
        return -1;
    }

    if (!g_is_initialized || g_session.sock < 0 || g_session.state != SESSION_STATE_AUTHENTICATED)
    {
        fprintf(stderr, "Client not authenticated\n");
        return -1;
    }

    sfts_ui_on_log_message("开始下载文件...", 0);

    // 开始文件传输
    int ret = client_download_file(&g_session, remote_path, local_path);

    if (ret != 0)
    {
        sfts_ui_on_log_message("下载文件请求失败", 1);
        return ret;
    }

    // 提取文件名
    char basename[256];
    const char *last_slash = strrchr(remote_path, '/');
    if (!last_slash)
    {
        last_slash = strrchr(remote_path, '\\');
    }

    if (last_slash)
    {
        strncpy(basename, last_slash + 1, sizeof(basename) - 1);
        basename[sizeof(basename) - 1] = '\0';
    }
    else
    {
        strncpy(basename, remote_path, sizeof(basename) - 1);
        basename[sizeof(basename) - 1] = '\0';
    }

    // 初始进度报告
    sfts_ui_on_transfer_progress(basename, 0, "下载初始化...");

    // 启动进度监控线程
    start_progress_monitor(basename);

    return 0;
}

// 删除文件
int sfts_client_delete_file(const char *remote_path)
{
    // 检查并尝试恢复会话状态
    int check_result = check_and_restore_session();
    if (check_result != 0)
    {
        // 会话状态异常，并且恢复尝试已启动或失败
        if (check_result > 0)
        {
            sfts_ui_on_log_message("正在恢复连接，请稍后再次尝试删除", 1);
            sfts_ui_on_delete_result(0, remote_path, "正在恢复连接，请稍后再试");
        }
        else
        {
            sfts_ui_on_log_message("连接已断开，无法删除文件", 1);
            sfts_ui_on_delete_result(0, remote_path, "连接已断开");
        }
        return -1;
    }

    if (!g_is_initialized || g_session.sock < 0 || g_session.state != SESSION_STATE_AUTHENTICATED)
    {
        fprintf(stderr, "Client not authenticated\n");
        sfts_ui_on_delete_result(0, remote_path, "连接已断开");
        return -1;
    }

    // 修改这里，添加重试机制
    int retry_count = 0;
    int max_retries = 2;
    int ret = -1;

    while (retry_count <= max_retries)
    {
        ret = client_delete_file(&g_session, remote_path);

        if (ret == 0)
        {
            // 成功删除
            sfts_ui_on_delete_result(1, remote_path, "文件删除成功");
            break;
        }
        else if (retry_count < max_retries)
        {
            // 重试前等待一小段时间
            fprintf(stderr, "[API] 删除文件失败，准备重试 (%d/%d)\n", retry_count + 1, max_retries);
            usleep(500000); // 500ms
            retry_count++;
        }
        else
        {
            // 所有重试都失败
            sfts_ui_on_delete_result(0, remote_path, "文件删除失败");
            break;
        }
    }

    return ret;
}

// 取消当前传输
int sfts_client_cancel_transfer()
{
    if (!g_is_initialized || g_session.sock < 0)
    {
        fprintf(stderr, "Client not initialized or not connected\n");
        return -1;
    }

    // 停止进度监控线程
    stop_progress_monitor();

    int ret = client_cancel_transfer(&g_session);

    if (ret == 0)
    {
        sfts_ui_on_log_message("传输已取消", 0);
    }
    else
    {
        sfts_ui_on_log_message("无法取消传输", 1);
    }

    return ret;
}

// 获取传输进度
int sfts_client_get_transfer_progress(int *percent_complete)
{
    if (!g_is_initialized || g_session.sock < 0 || !percent_complete)
    {
        return -1;
    }

    uint64_t transferred = 0, total = 0;
    int ret = client_get_transfer_progress(&g_session, &transferred, &total);

    if (ret == 0 && total > 0)
    {
        *percent_complete = (int)((transferred * 100) / total);
    }
    else
    {
        *percent_complete = 0;
    }

    return ret;
}

// 断开连接
int sfts_client_disconnect()
{
    if (!g_is_initialized)
    {
        return 0; // 未初始化，不需要断开
    }

    // 确保停止进度监控线程
    stop_progress_monitor();

    int ret = client_disconnect(&g_session);

    if (ret == 0)
    {
        client_cleanup();
        g_is_initialized = 0;
        sfts_ui_on_log_message("已断开连接", 0);
    }
    else
    {
        sfts_ui_on_log_message("断开连接失败", 1);
    }

    return ret;
}

// 用户退出登录
int sfts_client_logout()
{
    if (!g_is_initialized)
    {
        return 0; // 未初始化，无需退出登录
    }

    // 先断开连接
    int ret = client_disconnect(&g_session);

    if (ret == 0)
    {
        client_cleanup();
        g_is_initialized = 0;
        sfts_ui_on_log_message("已退出登录", 0);
    }
    else
    {
        sfts_ui_on_log_message("退出登录失败", 1);
    }

    return ret;
}

// 改变当前工作目录
int sfts_client_change_directory(const char *directory_path)
{
    if (!g_is_initialized || g_session.sock < 0 || g_session.state != SESSION_STATE_AUTHENTICATED)
    {
        fprintf(stderr, "Client not authenticated\n");
        return -1;
    }

    // 假设在client.c中有一个改变目录的函数，命名为client_change_directory
    // 如果实际上没有这个函数，我们需要在client.c中实现它
    // int ret = client_change_directory(&g_session, directory_path);

    // 为了简单起见，我们可以直接调用获取文件列表函数来访问子目录
    void *file_list = NULL;
    int file_count = 0;
    int ret = client_get_file_list(&g_session, directory_path, &file_list, &file_count);

    if (ret == 0 && file_list && file_count > 0)
    {
        // 将文件列表传递给GUI
        sfts_ui_on_file_list_updated((sfts_FileListItem_C *)file_list, file_count);

        // 释放C层分配的内存
        free(file_list);

        // 报告目录变更成功
        char message[512];
        snprintf(message, sizeof(message), "已进入目录: %s", directory_path);
        sfts_ui_on_log_message(message, 0);
    }
    else
    {
        char error_msg[512];
        snprintf(error_msg, sizeof(error_msg), "无法进入目录: %s", directory_path);
        sfts_ui_on_log_message(error_msg, 1);
    }

    return ret;
}